package com.ruoyi.washer.config;

import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.exception.HttpCodeException;
import com.wechat.pay.contrib.apache.httpclient.exception.NotFoundException;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
import java.security.Security;

@Configuration
public class WeChatConfig {

    @Value("${wx.appid}")
    private String appid;

    @Value("${wx.appsecret}")
    private String secret;

    @Value("${wx.mch_id}")
    private String mchId;

    @Value("${wx.key_v2}")
    private String key_v2;

    @Value("${wx.key_v3}")
    private String key_v3;

    @Value("${wx.notify_url}")
    private String notify_url;

    @Value("${wx.refund_notify_url}")
    private String refund_notify_url;

    @Value("${wx.private_key}")
    private String private_key;

    @Value("${wx.mch_serial_no}")
    private String mch_serial_no;

    @Value("${wx.service_id}")
    private String serviceId;

    @Bean
    public CloseableHttpClient wxHttpClient() throws GeneralSecurityException, IOException, HttpCodeException, NotFoundException {
        Security.setProperty("crypto.policy", "unlimited");
        PrivateKey merchantPrivateKey = PemUtil
                .loadPrivateKey(new ByteArrayInputStream(private_key.getBytes(StandardCharsets.UTF_8)));
        CertificatesManager certificatesManager = CertificatesManager.getInstance();
        certificatesManager.putMerchant(mchId,
                new WechatPay2Credentials(mchId,
                        new PrivateKeySigner(mch_serial_no, merchantPrivateKey)),
                key_v3.getBytes(StandardCharsets.UTF_8));
        return WechatPayHttpClientBuilder.create()
                .withMerchant(mchId, mch_serial_no, merchantPrivateKey)
                .withValidator(new WechatPay2Validator(certificatesManager.getVerifier(mchId)))
                .build();
    }


    public String getMchId() {
        return mchId;
    }

    public void setMchId(String mchId) {
        this.mchId = mchId;
    }

    public String getKey_v3() {
        return key_v3;
    }

    public void setKey_v3(String key_v3) {
        this.key_v3 = key_v3;
    }

    public String getAppid() {
        return appid;
    }

    public void setAppid(String appid) {
        this.appid = appid;
    }

    public String getSecret() {
        return secret;
    }

    public void setSecret(String secret) {
        this.secret = secret;
    }

    public String getKey_v2() {
        return key_v2;
    }

    public void setKey_v2(String key_v2) {
        this.key_v2 = key_v2;
    }

    public String getNotify_url() {
        return notify_url;
    }

    public void setNotify_url(String notify_url) {
        this.notify_url = notify_url;
    }

    public String getRefund_notify_url() {
        return refund_notify_url;
    }

    public void setRefund_notify_url(String refund_notify_url) {
        this.refund_notify_url = refund_notify_url;
    }

    public String getServiceId() {
        return serviceId;
    }

    public void setServiceId(String serviceId) {
        this.serviceId = serviceId;
    }

    public String getPrivate_key() {
        return private_key;
    }

    public void setPrivate_key(String private_key) {
        this.private_key = private_key;
    }

    public String getMch_serial_no() {
        return mch_serial_no;
    }

    public void setMch_serial_no(String mch_serial_no) {
        this.mch_serial_no = mch_serial_no;
    }
}
